import sys
import requests
import json
import importlib.util
import os
import re
import traceback
import time
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QListWidget, QTextEdit, QFrame, QGridLayout, QPushButton, QSizePolicy, QStackedWidget, QProgressBar, QFileDialog
from PyQt6.QtCore import Qt, QThread, QThreadPool, QRunnable, pyqtSignal, QTimer
from PyQt6.QtGui import QFont, QIcon, QPixmap
from PyQt6.QtGui import QPainter, QColor



def get_resource_path(relative_path):
    """获取资源文件的绝对路径，兼容开发环境和打包后的环境"""
    try:
        # PyInstaller创建临时文件夹，将路径存储在_MEIPASS中
        base_path = sys._MEIPASS
    except Exception:
        # 如果不是打包环境，使用当前目录
        base_path = os.path.abspath(".")
    
    return os.path.join(base_path, relative_path)

class DownloadThread(QThread):
    # 下载线程类
    download_finished = pyqtSignal()  # 下载完成信号
    download_progress = pyqtSignal(str)  # 下载进度信号
    
    def __init__(self, server_url, functions):
        super().__init__()
        self.server_url = server_url
        self.functions = functions
        
    def run(self):
        # 执行下载操作
        # 创建下载目录
        download_dir = "downloaded_py_files"
        if not os.path.exists(download_dir):
            os.makedirs(download_dir)
        
        for func in self.functions:
            function_id = func['id']
            py_files = func.get('py_files', [])
            for py_file in py_files:
                try:
                    self.download_progress.emit(f"正在下载: {py_file}")
                    url = f"{self.server_url}/api/download_py/{function_id}"
                    resp = requests.get(url, timeout=10)
                    if resp.status_code == 200:
                        file_path = os.path.join(download_dir, py_file)
                        with open(file_path, 'wb') as f:
                            f.write(resp.content)
                        self.download_progress.emit(f"成功下载: {file_path}")
                    else:
                        self.download_progress.emit(f"下载失败 {py_file}: {resp.status_code}")
                except Exception as e:
                    self.download_progress.emit(f"下载异常 {py_file}: {e}")
        
        self.download_finished.emit()

class DeviceInfoUI(QWidget):
    def __init__(self, device_info=None):
        super().__init__()
        self.setWindowTitle("Zero Tools")
        self.setWindowIcon(QIcon(get_resource_path("res/logo.png")))
        self.resize(900, 650)
        # 使用Windows自带标题栏
        self.setWindowFlags(Qt.WindowType.Window)
        if device_info is None:
            device_info = {
                "name": "UAV-001",
                "model": "X100",
                "id": "A1B2C3D4",
                "battery": "85%",
                "firmware": "v1.2.3"
            }
        self.server_url = "http://localhost:5000"  # 服务端地址
        
        # 进度管理
        self.current_task = None  # 当前执行的任务
        self.task_id = None  # 任务ID
        self.progress_timer = QTimer()  # 进度查询定时器
        self.progress_timer.timeout.connect(self.query_progress)
        
        # 缓存已加载的模块
        self.loaded_modules = {}
        
        self.init_ui(device_info)
        self.hide()  # 先隐藏界面
        
        # 显示加载界面
        self.show_loading_dialog()
        
        # 从服务端加载功能列表
        self.load_functions_from_server()
        
        # 添加欢迎日志
        self.log_info("Zero Tools 系统启动完成")
        self.log_info("请选择左侧功能开始操作")

    def show_loading_dialog(self):
        """显示加载对话框"""
        from PyQt6.QtWidgets import QDialog, QVBoxLayout, QLabel, QProgressBar
        
        # 创建蒙层
        self.overlay = QWidget(self)
        self.overlay.setStyleSheet("""
            QWidget {
                background-color: rgba(0, 0, 0, 0.6);
            }
        """)
        self.overlay.setGeometry(self.rect())
        self.overlay.show()
        
        self.loading_dialog = QDialog(self)
        self.loading_dialog.setWindowTitle("正在加载")
        self.loading_dialog.setFixedSize(300, 150)
        self.loading_dialog.setWindowFlags(Qt.WindowType.Dialog | Qt.WindowType.FramelessWindowHint)
        self.loading_dialog.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        self.loading_dialog.setModal(True)  # 设置为模态窗口
        
        # 设置样式
        self.loading_dialog.setStyleSheet("""
            QDialog {
                background: transparent;
            }
        """)
        
        # 创建内容容器
        content_widget = QWidget()
        content_widget.setStyleSheet("""
            QWidget {
                background: #4b5a7a;
                border-radius: 10px;
                border: 1px solid rgba(255, 255, 255, 0.3);
            }
        """)
        
        layout = QVBoxLayout(self.loading_dialog)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(content_widget)
        
        content_layout = QVBoxLayout(content_widget)
        content_layout.setContentsMargins(20, 20, 20, 20)
        content_layout.setSpacing(15)
        
        # 加载文本
        self.loading_label = QLabel("正在下载功能文件...")
        self.loading_label.setStyleSheet("""
            QLabel {
                color: #ffffff;
                font-size: 14px;
                font-weight: bold;
                background: transparent;
            }
        """)
        self.loading_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        content_layout.addWidget(self.loading_label)
        
        # 进度条
        self.loading_progress = QProgressBar()
        self.loading_progress.setStyleSheet("""
            QProgressBar {
                border: 2px solid #3a466b;
                border-radius: 5px;
                text-align: center;
                background-color: #2a3a5a;
            }
            QProgressBar::chunk {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0, 
                    stop:0 #1e88e5, 
                    stop:0.3 #42a5f5, 
                    stop:0.7 #64b5f6, 
                    stop:1 #90caf9);
                border-radius: 3px;
            }
        """)
        self.loading_progress.setRange(0, 0)  # 设置为不确定模式
        content_layout.addWidget(self.loading_progress)
        
        # 状态文本
        self.loading_status = QLabel("准备下载...")
        self.loading_status.setStyleSheet("""
            QLabel {
                color: #cfd8ff;
                font-size: 12px;
                background: transparent;
            }
        """)
        self.loading_status.setAlignment(Qt.AlignmentFlag.AlignCenter)
        content_layout.addWidget(self.loading_status)
        
        self.loading_dialog.show()

    def dynamic_import_pyfile(self, pyfile_path, func_name):
        """动态加载py文件并调用指定函数"""
        try:
            module_name = os.path.splitext(os.path.basename(pyfile_path))[0]
            
            # 检查是否已经加载过这个模块
            if module_name in self.loaded_modules:
                module = self.loaded_modules[module_name]
                print(f"使用缓存的模块: {module_name}")
            else:
                # 首次加载模块
                spec = importlib.util.spec_from_file_location(module_name, pyfile_path)
                if spec is None:
                    raise ImportError(f"Cannot find spec for {pyfile_path}")
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)
                self.loaded_modules[module_name] = module
                print(f"首次加载模块: {module_name}")
            
            func = getattr(module, func_name, None)
            if func is None:
                raise AttributeError(f"Function {func_name} not found in {pyfile_path}")
            return func
        except Exception as e:
            print(f"动态加载失败: {e}")
            return None

    def init_ui(self, device_info):
        # 创建主容器
        main_widget = QWidget()
        main_widget.setObjectName("mainWidget")
        main_layout = QVBoxLayout(main_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        
        # 设置主布局
        self.setLayout(QVBoxLayout(self))
        self.layout().addWidget(main_widget)
        self.layout().setContentsMargins(0, 0, 0, 0)
        # 主窗口背景渐变和标题栏样式
        self.setStyleSheet("""
            DeviceInfoUI {
                background: transparent;
            }
            QWidget#mainWidget {
                background: #173B77;
            }
            
            /* 全局滚动条样式 */
            QScrollBar:vertical {
                background: rgba(80, 100, 150, 0.3);
                width: 10px;
                border-radius: 5px;
                margin: 0px;
            }
            
            QScrollBar::handle:vertical {
                background: rgba(207, 216, 255, 0.6);
                border-radius: 5px;
                min-height: 20px;
                margin: 2px;
            }
            
            QScrollBar::handle:vertical:hover {
                background: rgba(207, 216, 255, 0.8);
            }
            
            QScrollBar::add-line:vertical,
            QScrollBar::sub-line:vertical {
                height: 0px;
                background: none;
            }
            
            QScrollBar:horizontal {
                background: rgba(80, 100, 150, 0.3);
                height: 10px;
                border-radius: 5px;
                margin: 0px;
            }
            
            QScrollBar::handle:horizontal {
                background: rgba(207, 216, 255, 0.6);
                border-radius: 5px;
                min-width: 20px;
                margin: 2px;
            }
            
            QScrollBar::handle:horizontal:hover {
                background: rgba(207, 216, 255, 0.8);
            }
            
            QScrollBar::add-line:horizontal,
            QScrollBar::sub-line:horizontal {
                width: 0px;
                background: none;
            }
        """)

        card = QFrame()
        card.setObjectName("card")
        card.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        card.setStyleSheet("background: transparent;")
        card_layout = QVBoxLayout(card)
        card_layout.setSpacing(12)
        card_layout.setContentsMargins(12, 12, 12, 12)

        # 设备信息区域
        info_frame = QFrame()
        info_frame.setStyleSheet("""
            QFrame {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #4b5a7a, stop:1 #5a6fae);
                border-radius: 16px;
                border: 1px solid rgba(255, 255, 255, 0.3);
            }
        """)
        info_layout = QHBoxLayout(info_frame)
        info_layout.setContentsMargins(24, 14, 24, 14)
        info_layout.setSpacing(12)

        # 圆形彩色图标
        icon_label = QLabel()
        icon_label.setStyleSheet("background: transparent; border: none;")
        # 加载logo图片
        logo_pixmap = QPixmap(get_resource_path("res/logo.png"))
        if not logo_pixmap.isNull():
            # 缩放图片到合适尺寸
            scaled_pixmap = logo_pixmap.scaled(48, 48, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
            icon_label.setPixmap(scaled_pixmap)
        else:
            # 如果图片加载失败，使用默认圆形图标
            icon_pix = QPixmap(48, 48)
            icon_pix.fill(Qt.GlobalColor.transparent)
            painter = QPainter(icon_pix)
            painter.setRenderHint(QPainter.RenderHint.Antialiasing)
            painter.setBrush(QColor("#409eff"))
            painter.setPen(Qt.PenStyle.NoPen)
            painter.drawEllipse(0, 0, 48, 48)
            painter.end()
            icon_label.setPixmap(icon_pix)
        info_layout.addWidget(icon_label)

        # 设备信息文本（表格式布局：设备名称单独一行，下方2x2）
        info_text_widget = QWidget()
        info_text_widget.setStyleSheet("background: transparent;")
        info_grid = QGridLayout(info_text_widget)
        info_grid.setContentsMargins(0, 0, 0, 0)
        info_grid.setHorizontalSpacing(24)
        info_grid.setVerticalSpacing(6)

        # 第一行：设备名称
        name_label = QLabel("设备名称：")
        name_label.setStyleSheet("font-size: 15px; color: #cfd8ff; background: transparent; border: none;")
        name_value = QLabel(str(device_info["name"]))
        name_value.setStyleSheet("font-size: 15px; color: #fff; font-weight: bold; background: transparent; border: none;")
        info_grid.addWidget(name_label, 0, 0)
        info_grid.addWidget(name_value, 0, 1, 1, 3)  # 跨3列

        # 第二、三行：2x2网格
        model_label = QLabel("型号：")
        model_label.setStyleSheet("font-size: 15px; color: #cfd8ff; background: transparent; border: none;")
        model_value = QLabel(str(device_info["model"]))
        model_value.setStyleSheet("font-size: 15px; color: #fff; font-weight: bold; background: transparent; border: none;")

        id_label = QLabel("设备ID：")
        id_label.setStyleSheet("font-size: 15px; color: #cfd8ff; background: transparent; border: none;")
        id_value = QLabel(str(device_info["id"]))
        id_value.setStyleSheet("font-size: 15px; color: #fff; font-weight: bold; background: transparent; border: none;")

        battery_label = QLabel("电量：")
        battery_label.setStyleSheet("font-size: 15px; color: #cfd8ff; background: transparent; border: none;")
        battery_value = QLabel(str(device_info["battery"]))
        battery_value.setStyleSheet("font-size: 15px; color: #fff; font-weight: bold; background: transparent; border: none;")

        firmware_label = QLabel("固件版本：")
        firmware_label.setStyleSheet("font-size: 15px; color: #cfd8ff; background: transparent; border: none;")
        firmware_value = QLabel(str(device_info["firmware"]))
        firmware_value.setStyleSheet("font-size: 15px; color: #fff; font-weight: bold; background: transparent; border: none;")

        # 第二行
        info_grid.addWidget(model_label, 1, 0)
        info_grid.addWidget(model_value, 1, 1)
        info_grid.addWidget(id_label, 1, 2)
        info_grid.addWidget(id_value, 1, 3)
        # 第三行
        info_grid.addWidget(battery_label, 2, 0)
        info_grid.addWidget(battery_value, 2, 1)
        info_grid.addWidget(firmware_label, 2, 2)
        info_grid.addWidget(firmware_value, 2, 3)

        info_layout.addWidget(info_text_widget)
        info_layout.addStretch()
        card_layout.addWidget(info_frame)

        # 下方HLayout
        h_layout = QHBoxLayout()
        h_layout.setSpacing(32)

        # 功能列表区域
        func_widget = QFrame()
        func_layout = QVBoxLayout(func_widget)
        func_layout.setContentsMargins(0, 0, 0, 0)
        func_layout.setSpacing(10)
        func_title = QLabel("功能列表")
        func_title.setStyleSheet("font-size: 15px; color: #cfd8ff; font-weight: bold; background: transparent;")
        func_layout.addWidget(func_title)
        self.func_list = QListWidget()
        self.func_list.addItems(["固件下载", "固件升级", "云台标定", "其他功能"])
        self.func_list.setMinimumWidth(150)
        self.func_list.setStyleSheet("""
            QListWidget {
                font-size: 16px;
                border-radius: 12px;
                background: rgba(80, 100, 150, 0.18);
                color: #fff;
                border: 1px solid rgba(255, 255, 255, 0.3);
                outline: none;
            }
            QListWidget::item {
                padding: 14px 10px;
                border-radius: 10px;
                margin: 2px 4px;
                outline: none;
            }
            QListWidget::item:hover:!selected {
                background: rgba(64, 158, 255, 0.3);
                border-radius: 10px;
            }
            QListWidget::item:pressed:!selected {
                background: rgba(64, 158, 255, 0.6);
                border-radius: 10px;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
            QListWidget::item:selected {
                background: #409eff;
                color: white;
                border-radius: 10px;
                font-weight: bold;
            }
            QListWidget::item:pressed:selected {
                background: #337ecc;
                color: white;
                border-radius: 10px;
                font-weight: bold;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        func_layout.addWidget(self.func_list)
        h_layout.addWidget(func_widget)
        h_layout.setStretch(0, 1)

        # 操作区域
        operation_widget = QFrame()
        operation_layout = QVBoxLayout(operation_widget)
        operation_layout.setContentsMargins(0, 0, 0, 0)
        operation_layout.setSpacing(10)
        self.operation_title = QLabel("公告")
        self.operation_title.setStyleSheet("font-size: 15px; color: #cfd8ff; font-weight: bold; background: transparent;")
        operation_layout.addWidget(self.operation_title)
        
        # 使用QStackedWidget
        self.operation_stack = QStackedWidget()
        self.operation_stack.setStyleSheet("""
            QStackedWidget {
                background: rgba(80, 100, 150, 0.18);
                border-radius: 12px;
                border: 1px solid rgba(255, 255, 255, 0.3);
            }
        """)
        
        # 创建默认提示页面
        self.create_default_page()
        
        # 创建各个功能页面
        self.create_firmware_download_page()
        self.create_firmware_upgrade_page()
        self.create_gimbal_calibration_page()
        self.create_other_functions_page()
        
        operation_layout.addWidget(self.operation_stack)
        h_layout.addWidget(operation_widget)
        h_layout.setStretch(1, 2)
        
        # 绑定功能列表点击事件
        self.func_list.itemClicked.connect(self.on_function_selected)

        card_layout.addLayout(h_layout)
        
        # 日志输出显示区域
        log_widget = QWidget()
        log_layout = QVBoxLayout(log_widget)
        log_layout.setContentsMargins(0, 0, 0, 0)
        log_layout.setSpacing(8)
        
        log_title = QLabel("日志输出")
        log_title.setStyleSheet("font-size: 15px; color: #cfd8ff; font-weight: bold; background: transparent;")
        log_layout.addWidget(log_title)
        
        self.log_output = QTextEdit()
        self.log_output.setReadOnly(True)
        self.log_output.setAcceptRichText(True)
        self.log_output.setStyleSheet("""
            QTextEdit {
                background: rgba(80, 100, 150, 0.18);
                border: 1px solid rgba(255, 255, 255, 0.3);
                border-radius: 8px;
                font-size: 13px;
                color: #e0e6f6;
                padding: 8px;
                font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            }
        """)
        self.log_output.setMinimumHeight(180)
        self.log_output.setPlaceholderText("系统日志将在这里显示...")
        
        # 连接滚动条信号，用于跟踪用户是否手动滚动
        self.log_output.verticalScrollBar().valueChanged.connect(self.on_log_scroll_changed)
        self.user_scrolled = False  # 标记用户是否手动滚动
        
        log_layout.addWidget(self.log_output)
        
        card_layout.addWidget(log_widget)

        main_layout.addWidget(card) 

    def create_firmware_download_page(self):
        """固件下载页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 进度显示区域
        progress_widget = QWidget()
        progress_layout = QVBoxLayout(progress_widget)
        progress_layout.setContentsMargins(0, 0, 0, 0)
        progress_layout.setSpacing(10)
        
        # 进度百分比
        self.download_progress_label = QLabel("0%")
        self.download_progress_label.setStyleSheet("font-size: 24px; color: #333; font-weight: bold; background: transparent;")
        self.download_progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        progress_layout.addWidget(self.download_progress_label)
        
        # 进度条
        self.download_progress_bar = QProgressBar()
        self.download_progress_bar.setRange(0, 100)
        self.download_progress_bar.setValue(0)
        self.download_progress_bar.setFixedHeight(8)
        self.download_progress_bar.setTextVisible(False)
        self.download_progress_bar.setStyleSheet("""
            QProgressBar {
                border-radius: 4px;
                background: #f0f0f0;
            }
            QProgressBar::chunk {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0, 
                    stop:0 #1e88e5, 
                    stop:0.3 #42a5f5, 
                    stop:0.7 #64b5f6, 
                    stop:1 #90caf9);
                border-radius: 4px;
            }
        """)
        progress_layout.addWidget(self.download_progress_bar)
        
        layout.addWidget(progress_widget)
        
        # 固件列表显示区域
        self.firmware_list = QListWidget()
        self.firmware_list.setMinimumHeight(200)
        self.firmware_list.setStyleSheet("""
            QListWidget {
                background: #f8f9fa;
                border: 1px solid #ddd;
                border-radius: 8px;
                font-size: 14px;
                color: #333;
                border: none;
                outline: none;
            }
            QListWidget::item {
                padding: 8px 12px;
                border-radius: 6px;
                margin: 2px 4px;
                outline: none;
            }
            QListWidget::item:hover:!selected {
                background: rgba(64, 158, 255, 0.3);
                border-radius: 6px;
            }
            QListWidget::item:pressed:!selected {
                background: rgba(64, 158, 255, 0.6);
                border-radius: 6px;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
            QListWidget::item:selected {
                background: #409eff;
                color: white;
                border-radius: 6px;
                font-weight: bold;
            }
            QListWidget::item:pressed:selected {
                background: #337ecc;
                color: white;
                border-radius: 6px;
                font-weight: bold;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        
        layout.addWidget(self.firmware_list)
        
        # 动态获取可下载的固件列表
        self.load_available_firmware()
        
        # 下载按钮
        download_layout = QHBoxLayout()
        download_btn = QPushButton("下载所选固件")
        download_btn.setFixedHeight(40)
        download_btn.setFixedWidth(180)
        download_btn.setStyleSheet("""
            QPushButton {
                background: #409eff;
                color: white;
                border: none;
                border-radius: 20px;
                font-size: 16px;
                font-weight: bold;
                outline: none;
            }
            QPushButton:hover {
                background: #66b1ff;
            }
            QPushButton:pressed {
                background: #337ecc;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        download_btn.clicked.connect(self.on_download_firmware_clicked)
        download_layout.addWidget(download_btn)
        layout.addLayout(download_layout)
        
        # layout.addStretch()
        
        self.operation_stack.addWidget(page)
    
    def create_firmware_upgrade_page(self):
        """固件升级页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 进度显示区域
        progress_widget = QWidget()
        progress_layout = QVBoxLayout(progress_widget)
        progress_layout.setContentsMargins(0, 0, 0, 0)
        progress_layout.setSpacing(10)
        
        # 进度百分比
        self.progress_label = QLabel("0%")
        self.progress_label.setStyleSheet("font-size: 24px; color: #333; font-weight: bold; background: transparent;")
        self.progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        progress_layout.addWidget(self.progress_label)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        self.progress_bar.setFixedHeight(8)
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border-radius: 4px;
                background: #f0f0f0;
            }
            QProgressBar::chunk {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0, 
                    stop:0 #1e88e5, 
                    stop:0.3 #42a5f5, 
                    stop:0.7 #64b5f6, 
                    stop:1 #90caf9);
                border-radius: 4px;
            }
        """)
        progress_layout.addWidget(self.progress_bar)
        
        layout.addWidget(progress_widget)
        
        # 固件路径输入区域
        path_widget = QWidget()
        path_layout = QHBoxLayout(path_widget)
        path_layout.setContentsMargins(0, 0, 0, 0)
        path_layout.setSpacing(10)
        
        path_label = QLabel("固件路径:")
        path_label.setStyleSheet("font-size: 14px; color: #333; background: transparent;")
        path_layout.addWidget(path_label)
        
        from PyQt6.QtWidgets import QLineEdit, QFileDialog
        self.path_input = QLineEdit()
        self.path_input.setText("")
        self.path_input.setStyleSheet("""
            QLineEdit {
                background: white;
                color: #333;
                border: 1px solid #ddd;
                border-radius: 6px;
                padding: 8px;
                font-size: 14px;
            }
            QLineEdit:focus {
                border: 1px solid #409eff;
                outline: none;
            }
        """)
        path_layout.addWidget(self.path_input)
        
        # 浏览按钮
        browse_btn = QPushButton("浏览")
        browse_btn.setFixedSize(60, 36)
        browse_btn.setStyleSheet("""
            QPushButton {
                background: #409eff;
                color: white;
                border: none;
                border-radius: 6px;
                font-size: 14px;
                outline: none;
            }
            QPushButton:hover {
                background: #66b1ff;
            }
            QPushButton:pressed {
                background: #337ecc;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        browse_btn.clicked.connect(self.browse_firmware_file)
        path_layout.addWidget(browse_btn)
        
        layout.addWidget(path_widget)
        
        # 升级按钮
        upgrade_layout = QHBoxLayout()
        upgrade_btn = QPushButton("升级")
        upgrade_btn.setFixedHeight(40)
        upgrade_btn.setFixedWidth(180)
        upgrade_btn.setStyleSheet("""
            QPushButton {
                background: #409eff;
                color: white;
                border: none;
                border-radius: 20px;
                font-size: 16px;
                font-weight: bold;
                outline: none;
            }
            QPushButton:hover {
                background: #66b1ff;
            }
            QPushButton:pressed {
                background: #337ecc;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        upgrade_btn.clicked.connect(self.on_upgrade_firmware_clicked)
        upgrade_layout.addWidget(upgrade_btn)
        layout.addLayout(upgrade_layout)
        
        # layout.addStretch()
        
        self.operation_stack.addWidget(page)
    
    def create_gimbal_calibration_page(self):
        """云台标定页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(20)
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 进度显示区域
        progress_widget = QWidget()
        progress_layout = QVBoxLayout(progress_widget)
        progress_layout.setContentsMargins(0, 0, 0, 0)
        progress_layout.setSpacing(10)
        
        # 进度百分比
        self.calibration_progress_label = QLabel("0%")
        self.calibration_progress_label.setStyleSheet("font-size: 24px; color: #333; font-weight: bold; background: transparent;")
        self.calibration_progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        progress_layout.addWidget(self.calibration_progress_label)
        
        # 进度条
        self.calibration_progress_bar = QProgressBar()
        self.calibration_progress_bar.setRange(0, 100)
        self.calibration_progress_bar.setValue(0)
        self.calibration_progress_bar.setFixedHeight(8)
        self.calibration_progress_bar.setTextVisible(False)
        self.calibration_progress_bar.setStyleSheet("""
            QProgressBar {
                border-radius: 4px;
                background: #f0f0f0;
            }
            QProgressBar::chunk {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0, 
                    stop:0 #1e88e5, 
                    stop:0.3 #42a5f5, 
                    stop:0.7 #64b5f6, 
                    stop:1 #90caf9);
                border-radius: 4px;
            }
        """)
        progress_layout.addWidget(self.calibration_progress_bar)
        
        layout.addWidget(progress_widget)
        
        # 复选框区域
        checkbox_widget = QWidget()
        checkbox_layout = QHBoxLayout(checkbox_widget)
        checkbox_layout.setContentsMargins(0, 0, 0, 0)
        checkbox_layout.setSpacing(20)
        
        from PyQt6.QtWidgets import QCheckBox
        self.rough_calibration = QCheckBox("粗略标定")
        self.linear_calibration = QCheckBox("线性标定")
        self.imu_repair = QCheckBox("IMU 数据修复")
        
        for checkbox in (self.rough_calibration, self.linear_calibration, self.imu_repair):
            checkbox.setStyleSheet("""
                QCheckBox {
                    font-size: 14px;
                    color: #333;
                    background: transparent;
                }
                QCheckBox::indicator {
                    width: 16px;
                    height: 16px;
                }
                QCheckBox::indicator:unchecked {
                    border: 2px solid #ddd;
                    background: white;
                    border-radius: 3px;
                }
                QCheckBox::indicator:checked {
                    border: 2px solid #4CAF50;
                    background: #4CAF50;
                    border-radius: 3px;
                }
            """)
            checkbox_layout.addWidget(checkbox)
        
        # checkbox_layout.addStretch()
        layout.addWidget(checkbox_widget)
        
        # 执行标定按钮
        calibrate_layout = QHBoxLayout()
        calibrate_btn = QPushButton("执行标定")
        calibrate_btn.setFixedHeight(40)
        calibrate_btn.setFixedWidth(180)
        calibrate_btn.setStyleSheet("""
            QPushButton {
                background: #409eff;
                color: white;
                border: none;
                border-radius: 20px;
                font-size: 16px;
                font-weight: bold;
                outline: none;
            }
            QPushButton:hover {
                background: #66b1ff;
            }
            QPushButton:pressed {
                background: #337ecc;
                transform: translateY(2px);
                transition: all 0.1s ease;
            }
        """)
        calibrate_btn.clicked.connect(self.on_calibrate_gimbal_clicked)
        calibrate_layout.addWidget(calibrate_btn)
        layout.addLayout(calibrate_layout)
        
        # layout.addStretch()
        
        self.operation_stack.addWidget(page)
    
    def create_other_functions_page(self):
        """其他功能页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 标题
        title = QLabel("其他功能")
        title.setStyleSheet("font-size: 18px; color: #fff; font-weight: bold; background: transparent;")
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 提示信息
        desc = QLabel("更多功能敬请期待...")
        desc.setStyleSheet("font-size: 16px; color: #cfd8ff; background: transparent;")
        desc.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(desc)
        
        layout.addStretch()
        
        self.operation_stack.addWidget(page)
    
    def create_default_page(self):
        """公告页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(30, 30, 30, 30)
        layout.setSpacing(20)
        
        # 公告标题
        title_label = QLabel("系统公告")
        title_label.setFont(QFont("微软雅黑", 24, QFont.Weight.Bold))
        title_label.setStyleSheet("color: #ffffff; background: transparent; margin-bottom: 10px;")
        title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title_label)
        
        # 公告内容容器
        content_widget = QWidget()
        content_widget.setStyleSheet("""
            QWidget {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #4b5a7a, stop:1 #5a6fae);
                border-radius: 15px;
                border: 1px solid rgba(255, 255, 255, 0.2);
            }
        """)
        content_layout = QVBoxLayout(content_widget)
        content_layout.setContentsMargins(25, 25, 25, 25)
        content_layout.setSpacing(15)
        
        # 公告内容
        announcements = [
            {
                "title": "欢迎使用",
                "content": "Zero Tools 无人机管理工具 v1.0.0",
                "date": "2024-01-15"
            },
            {
                "title": "使用提醒",
                "content": "请确保设备已连接，网络状态正常",
                "date": "2024-01-15"
            }
        ]
        
        for announcement in announcements:
            # 创建单个公告项
            announcement_widget = QWidget()
            announcement_widget.setStyleSheet("""
                QWidget {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 10px;
                    border: 1px solid rgba(255, 255, 255, 0.1);
                }
            """)
            announcement_layout = QVBoxLayout(announcement_widget)
            announcement_layout.setContentsMargins(15, 15, 15, 15)
            announcement_layout.setSpacing(8)
            
            # 公告标题和日期
            header_layout = QHBoxLayout()
            header_layout.setContentsMargins(0, 0, 0, 0)
            
            title = QLabel(announcement["title"])
            title.setFont(QFont("微软雅黑", 14, QFont.Weight.Bold))
            title.setStyleSheet("color: #ffffff; background: transparent;")
            
            date = QLabel(announcement["date"])
            date.setStyleSheet("color: #cfd8ff; font-size: 12px; background: transparent; opacity: 0.7;")
            
            header_layout.addWidget(title)
            header_layout.addStretch()
            header_layout.addWidget(date)
            
            announcement_layout.addLayout(header_layout)
            
            # 公告内容
            content = QLabel(announcement["content"])
            content.setWordWrap(True)
            content.setStyleSheet("color: #e0e6f6; font-size: 13px; background: transparent; line-height: 1.4;")
            
            announcement_layout.addWidget(content)
            content_layout.addWidget(announcement_widget)
        
        layout.addWidget(content_widget)
        layout.addStretch()
        
        self.operation_stack.addWidget(page)
    
    def on_function_selected(self, item):
        """功能列表选中事件"""
        function_name = item.text()
        
        # 页面切换逻辑
        if function_name == "固件下载":
            self.operation_stack.setCurrentIndex(1)
            self.operation_title.setText("操作区域")
        elif function_name == "固件升级":
            self.operation_stack.setCurrentIndex(2)
            self.operation_title.setText("操作区域")
        elif function_name == "云台标定":
            self.operation_stack.setCurrentIndex(3)
            self.operation_title.setText("操作区域")
        elif function_name == "其他功能":
            self.operation_stack.setCurrentIndex(4)
            self.operation_title.setText("操作区域")

    def browse_firmware_file(self):
        """浏览固件文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "选择固件文件",
            "",
            "固件文件 (*.bin *.hex);;所有文件 (*.*)"
        )
        if file_path:
            self.path_input.setText(file_path) 

    def on_download_firmware_clicked(self):
        selected_items = self.firmware_list.selectedItems()
        if not selected_items:
            self.log_warning("请选择要下载的固件！")
            return

        selected_firmware = selected_items[0].text()
        self.log_info(f"开始下载固件: {selected_firmware}")

        # 解析固件版本号 - 适配新格式 固件版本 v123 - 最新稳定版本"
        version_match = re.search(r"固件版本 (v\d+\.\d+\.\d+)", selected_firmware)
        if version_match:
            firmware_version = version_match.group(1)
            self.log_info(f"检测到固件版本: {firmware_version}")
        else:
            self.log_error("无法解析固件版本，请确保固件名称格式正确。")
            return

        # 动态加载并调用下载功能
        try:
            pyfile_path = os.path.join("downloaded_py_files", "download_firmware.py")
            if os.path.exists(pyfile_path):
                func = self.dynamic_import_pyfile(pyfile_path, "download_firmware")
                if func:
                    device_id = "UAV-001"
                    
                    # 启动任务并设置定时器查询进度
                    self.current_task = "download_firmware"
                    self.task_id = f"download_{device_id}_{firmware_version}"
                    
                    # 在后台线程中执行下载任务
                    import threading
                    def run_download():
                        try:
                            print(f"开始执行固件下载任务: {device_id}, 版本: {firmware_version}")
                            result = func(device_id, firmware_version)
                            print(f"固件下载任务启动结果: {result}")
                            self.log_success(f"下载任务启动成功！任务ID: {self.task_id}")
                        except Exception as e:
                            print(f"固件下载任务启动异常: {e}")
                            self.log_error(f"下载任务启动失败: {e}")
                            self.current_task = None
                            self.task_id = None
                    
                    download_thread = threading.Thread(target=run_download)
                    download_thread.daemon = True
                    download_thread.start()
                    
                    # 启动进度查询定时器，每200ms查询一次
                    self.progress_timer.start(200)
                    
                else:
                    self.log_error("无法加载下载功能函数")
            else:
                    self.log_error(f"py文件不存在: {pyfile_path}")
        except Exception as e:
            self.log_error(f"固件下载异常: {e}")

    def on_upgrade_firmware_clicked(self):
        firmware_path = self.path_input.text()
        if not firmware_path:
            self.log_warning("请选择固件文件！")
            return

        self.log_info(f"开始固件升级: {firmware_path}")

        try:
            pyfile_path = os.path.join("downloaded_py_files", "upgrade_firmware.py")
            if os.path.exists(pyfile_path):
                func = self.dynamic_import_pyfile(pyfile_path, "upgrade_firmware")
                if func:
                    device_id = "UAV-001"
                    
                    # 启动任务并设置定时器查询进度
                    self.current_task = "upgrade_firmware"
                    self.task_id = f"upgrade_{device_id}_{os.path.basename(firmware_path)}"
                    
                    # 在后台线程中执行升级任务
                    import threading
                    def run_upgrade():
                        try:
                            result = func(device_id, firmware_path)
                            self.log_success(f"升级任务启动成功！任务ID: {self.task_id}")
                        except Exception as e:
                            self.log_error(f"升级任务启动失败: {e}")
                            self.current_task = None
                            self.task_id = None
                    
                    upgrade_thread = threading.Thread(target=run_upgrade)
                    upgrade_thread.daemon = True
                    upgrade_thread.start()
                    
                    # 启动进度查询定时器，每200ms查询一次
                    self.progress_timer.start(200)
                    
                else:
                    self.log_error("无法加载固件升级功能函数")
            else:
                self.log_error(f"py文件不存在: {pyfile_path}")
        except Exception as e:
            self.log_error(f"固件升级异常: {e}")

    def on_calibrate_gimbal_clicked(self):
        self.log_info("执行云台标定按钮点击")
        selected_types = []
        if self.rough_calibration.isChecked():
            selected_types.append("rough")
        if self.linear_calibration.isChecked():
            selected_types.append("linear")
        if self.imu_repair.isChecked():
            selected_types.append("imu_repair")

        if not selected_types:
            self.log_warning("请选择至少一种标定类型！")
            return

        self.log_info(f"选择的标定类型: {selected_types}")

        try:
            pyfile_path = os.path.join("downloaded_py_files", "gimbal_calibration.py")
            if os.path.exists(pyfile_path):
                func = self.dynamic_import_pyfile(pyfile_path, "calibrate_gimbal")
                if func:
                    device_id = "UAV-001"
                    
                    # 启动任务并设置定时器查询进度
                    self.current_task = "gimbal_calibration"
                    self.task_id = f"calibration_{device_id}_{'_'.join(selected_types)}"
                    
                    # 在后台线程中执行标定任务
                    import threading
                    def run_calibration():
                        try:
                            print(f"开始执行云台标定任务: {device_id}, 类型: {selected_types}")
                            result = func(device_id, selected_types)
                            print(f"云台标定任务启动结果: {result}")
                            self.log_success(f"标定任务启动成功！任务ID: {self.task_id}")
                        except Exception as e:
                            print(f"云台标定任务启动异常: {e}")
                            self.log_error(f"标定任务启动失败: {e}")
                            self.current_task = None
                            self.task_id = None
                    
                    calibration_thread = threading.Thread(target=run_calibration)
                    calibration_thread.daemon = True
                    calibration_thread.start()
                    
                    # 启动进度查询定时器，每200ms查询一次
                    self.progress_timer.start(200)
                    
                else:
                    self.log_error("无法加载云台标定功能函数")
            else:
                self.log_error(f"py文件不存在: {pyfile_path}")
        except Exception as e:
            self.log_error(f"云台标定异常: {e}")

    def on_other_function_clicked(self, function_type):
        """其他功能按钮点击事件"""
        function_names = {
            "diagnostics": "设备诊断",
            "optimization": "系统优化", 
            "backup": "数据备份",
            "analysis": "飞行数据分析",
            "network_test": "网络测试"
        }
        
        function_name = function_names.get(function_type, function_type)
        self.other_log_output.append(f"开始执行{function_name}...")
        
        try:
            pyfile_path = os.path.join("downloaded_py_files", "other_functions.py")
            if os.path.exists(pyfile_path):
                func = self.dynamic_import_pyfile(pyfile_path, "other_functions")
                if func:
                    device_id = "UAV-001"
                    
                    # 启动任务并设置定时器查询进度
                    self.current_task = f"other_function_{function_type}"
                    self.task_id = f"{function_type}_{device_id}_{int(time.time())}"
                    
                    # 在后台线程中执行功能任务
                    import threading
                    def run_other_function():
                        try:
                            print(f"开始执行{function_name}任务: {device_id}")
                            result = func(device_id, function_type)
                            print(f"{function_name}任务启动结果: {result}")
                            self.other_log_output.append(f"{function_name}任务启动成功！任务ID: {self.task_id}")
                        except Exception as e:
                            print(f"{function_name}任务启动异常: {e}")
                            self.other_log_output.append(f"{function_name}任务启动失败: {e}")
                            self.current_task = None
                            self.task_id = None
                    
                    function_thread = threading.Thread(target=run_other_function)
                    function_thread.daemon = True
                    function_thread.start()
                    
                    # 启动进度查询定时器，每200ms查询一次
                    self.progress_timer.start(200)
                    
                else:
                    self.other_log_output.append("无法加载其他功能函数")
            else:
                self.other_log_output.append(f"py文件不存在: {pyfile_path}")
        except Exception as e:
            self.other_log_output.append(f"{function_name}异常: {e}")

    def load_available_firmware(self):
        """动态加载可下载的固件列表"""
        try:
            pyfile_path = os.path.join("downloaded_py_files", "download_firmware.py")
            if os.path.exists(pyfile_path):
                func = self.dynamic_import_pyfile(pyfile_path, "get_available_firmware")
                if func:
                    firmware_list = func()
                    self.firmware_list.clear()
                    for firmware in firmware_list:
                        version = firmware.get("version", "Unknown")
                        size = firmware.get("size", "")
                        description = firmware.get("description", "")
                        display_text = f"固件版本 {version} ({size}) - {description}"
                        self.firmware_list.addItem(display_text)
                    print(f"成功加载 {len(firmware_list)} 个固件版本")
                else:
                    print("无法加载get_available_firmware函数")
                    # 添加默认固件列表作为备选
                    self.firmware_list.addItems([
                        "固件版本 v12.3 (5MB) - 最新稳定版本",
                        "固件版本 v10.22",
                        "固件版本 v12.1 历史版本"
                    ])
            else:
                print(f"py文件不存在: {pyfile_path}")
                # 添加默认固件列表作为备选
                self.firmware_list.addItems([
                    "固件版本 v12.3 (5MB) - 最新稳定版本",
                    "固件版本 v10.22",
                    "固件版本 v12.1本"
                ])
        except Exception as e:
            print(f"加载固件列表异常: {e}")
            # 添加默认固件列表作为备选
            self.firmware_list.addItems([
                "固件版本 v12.3 (5MB) - 最新稳定版本",
                "固件版本 v10.22",
                "固件版本 v12.1 历史版本"
            ])

    def load_functions_from_server(self):
        """从服务端获取功能列表并展示"""
        try:
            url = f"{self.server_url}/api/functions"
            resp = requests.get(url, timeout=3)
            if resp.status_code == 200:
                functions = resp.json()
                self.func_list.clear()
                # 可根据需要映射为中文名
                name_map = {
                    "download_firmware": "固件下载",
                    "upgrade_firmware": "固件升级",
                    "gimbal_calibration": "云台标定",
                    "other_functions": "其他功能"
                }
                for func in functions:
                    func_name = name_map.get(func['id'], func['id'])
                    self.func_list.addItem(func_name)
                    # 打印功能的py文件
                    py_files = func.get('py_files', [])
                    if py_files:
                        print(f"功能 {func_name} 的py文件: {py_files}")
                
                # 启动下载线程
                self.download_thread = DownloadThread(self.server_url, functions)
                self.download_thread.download_progress.connect(self.on_download_progress)
                self.download_thread.download_finished.connect(self.on_download_finished)
                self.download_thread.start()
            else:
                self.func_list.clear()
                self.func_list.addItem("获取功能失败")
                # 关闭加载对话框并显示主界面
                if hasattr(self, 'loading_dialog'):
                    self.loading_dialog.close()
                    self.loading_dialog = None
                # 移除蒙层
                if hasattr(self, 'overlay'):
                    self.overlay.hide()
                    self.overlay.deleteLater()
                    delattr(self, 'overlay')
                self.show()  # 显示界面
        except Exception as e:
            self.func_list.clear()
            self.func_list.addItem(f"功能获取异常: {e}")
            # 关闭加载对话框并显示主界面
            if hasattr(self, 'loading_dialog'):
                self.loading_dialog.close()
                self.loading_dialog = None
            # 移除蒙层
            if hasattr(self, 'overlay'):
                self.overlay.hide()
                self.overlay.deleteLater()
                delattr(self, 'overlay')
            self.show()  # 显示界面

    def on_download_progress(self, message):
        """下载进度回调"""
        print(message)
        # 更新加载对话框状态
        if hasattr(self, 'loading_status'):
            self.loading_status.setText(message)

    def log_message(self, message, level="INFO"):
        """标准日志输出方法"""
        import datetime
        
        # 获取当前时间
        timestamp = datetime.datetime.now().strftime("%H:%M:%S")
        
        # 根据日志级别设置颜色
        level_colors = {
            "INFO": "#ffffff",
            "WARNING": "#ffaa00",
            "ERROR": "#ff4444",
            "SUCCESS": "#44ff44",
            "DEBUG": "#888888"
        }
        color = level_colors.get(level, "#ffffff")
        
        # 格式化日志消息
        log_entry = f'<span style="color: #888888;">[{timestamp}]</span> <span style="color: {color};">[{level}]</span> {message}'
        
        # 添加消息
        self.log_output.append(log_entry)
        
        # 如果用户没有手动滚动，则自动滚动到底部
        if not self.user_scrolled:
            # 使用QTimer延迟滚动，确保内容已更新
            from PyQt6.QtCore import QTimer
            QTimer.singleShot(10, lambda: self.scroll_to_bottom())
    
    def scroll_to_bottom(self):
        """滚动到日志底部"""
        scrollbar = self.log_output.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())
        # 确保滚动到底部
        self.log_output.ensureCursorVisible()
    
    def on_log_scroll_changed(self, value):
        """日志滚动条变化处理"""
        scrollbar = self.log_output.verticalScrollBar()
        # 如果用户滚动到接近底部，重置手动滚动标记
        if value >= scrollbar.maximum() - 10:
            self.user_scrolled = False
        else:
            self.user_scrolled = True

    def log_info(self, message):
        """信息日志"""
        self.log_message(message, "INFO")
    
    def log_warning(self, message):
        """警告日志"""
        self.log_message(message, "WARNING")
    
    def log_error(self, message):
        """错误日志"""
        self.log_message(message, "ERROR")
    
    def log_success(self, message):
        """成功日志"""
        self.log_message(message, "SUCCESS")
    
    def log_debug(self, message):
        """调试日志"""
        self.log_message(message, "DEBUG")

    def query_progress(self):
        """定时查询任务进度"""
        if not self.current_task or not self.task_id:
            self.progress_timer.stop()
            return
            
        try:
            # 根据当前任务类型查询对应的进度
            if self.current_task == "download_firmware":
                pyfile_path = os.path.join("downloaded_py_files", "download_firmware.py")
                if os.path.exists(pyfile_path):
                    func = self.dynamic_import_pyfile(pyfile_path, "check_download_progress")
                    if func:
                        progress = func()  # 直接返回进度数值
                        
                        print(f"固件下载进度: {progress}%")
                        
                        # 更新进度条
                        self.download_progress_bar.setValue(progress)
                        self.download_progress_label.setText(f"{progress}%")
                        self.log_info(f"固件下载进度: {progress}%")
                        
                        # 检查是否完成
                        if progress >= 100:
                            self.progress_timer.stop()
                            self.current_task = None
                            self.task_id = None
                            self.log_success("固件下载完成！")
                            
            elif self.current_task == "upgrade_firmware":
                pyfile_path = os.path.join("downloaded_py_files", "upgrade_firmware.py")
                if os.path.exists(pyfile_path):
                    func = self.dynamic_import_pyfile(pyfile_path, "check_upgrade_progress")
                    if func:
                        progress = func()  # 直接返回进度数值
                        
                        # 更新进度条
                        self.progress_bar.setValue(progress)
                        self.progress_label.setText(f"{progress}%")
                        self.log_info(f"固件升级进度: {progress}%")
                        
                        # 检查是否完成
                        if progress >= 100:
                            self.progress_timer.stop()
                            self.current_task = None
                            self.task_id = None
                            self.log_success("固件升级完成！")
                            
            elif self.current_task == "gimbal_calibration":
                pyfile_path = os.path.join("downloaded_py_files", "gimbal_calibration.py")
                if os.path.exists(pyfile_path):
                    func = self.dynamic_import_pyfile(pyfile_path, "get_calibration_status")
                    if func:
                        progress = func()  # 直接返回进度数值
                        
                        # 更新进度条
                        self.calibration_progress_bar.setValue(progress)
                        self.calibration_progress_label.setText(f"{progress}%")
                        self.log_info(f"云台标定进度: {progress}%")
                        
                        # 检查是否完成
                        if progress >= 100:
                            self.progress_timer.stop()
                            self.current_task = None
                            self.task_id = None
                            self.log_success("云台标定完成！")
                    else:
                        print("无法加载get_calibration_status函数")
                else:
                    print(f"云台标定py文件不存在: {pyfile_path}")
            
            elif self.current_task.startswith("other_function_"):
                # 处理其他功能的进度查询
                function_type = self.current_task.replace("other_function_", "")
                pyfile_path = os.path.join("downloaded_py_files", "other_functions.py")
                if os.path.exists(pyfile_path):
                    # 尝试获取进度信息
                    try:
                        # 这里可以根据不同的功能类型调用不同的进度查询函数
                        # 由于other_functions.py中的函数是同步执行的，我们可以模拟进度
                        import random
                        progress = random.randint(0, 100)  # 模拟进度
                        
                        function_names = {
                            "diagnostics": "设备诊断",
                            "optimization": "系统优化", 
                            "backup": "数据备份",
                            "analysis": "飞行数据分析",
                            "network_test": "网络测试"
                        }
                        function_name = function_names.get(function_type, function_type)
                        
                        self.other_log_output.append(f"[{function_name} {progress}%]")
                        
                        # 检查是否完成
                        if progress >= 100:
                            self.progress_timer.stop()
                            self.current_task = None
                            self.task_id = None
                            self.other_log_output.append(f"{function_name}完成！")
                    except Exception as e:
                        print(f"其他功能进度查询异常: {e}")
                else:
                    print(f"其他功能py文件不存在: {pyfile_path}")
                            
        except Exception as e:
            self.log_error(f"查询进度异常: {e}")
            self.progress_timer.stop()
            self.current_task = None
            self.task_id = None

    def on_download_finished(self):
        """下载完成回调"""
        print("所有文件下载完成！")
        
        # 关闭加载对话框
        if hasattr(self, 'loading_dialog'):
            self.loading_dialog.close()
            self.loading_dialog = None
        # 移除蒙层
        if hasattr(self, 'overlay'):
            self.overlay.hide()
            self.overlay.deleteLater()
            delattr(self, 'overlay')
        
        # 显示主界面
        self.show()

    def resizeEvent(self, event):
        """窗口大小变化事件"""
        super().resizeEvent(event)
        # 更新蒙层大小
        if hasattr(self, 'overlay'):
            self.overlay.setGeometry(self.rect())

 